package com.cloud.common.ribbon;

import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ServerStats;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Slf4j
public class RibbonServerPing implements IPing {

    private RestTemplate restTemplate;
    private RibbonBestRule ribbonBestRule;

    public RibbonServerPing(RibbonBestRule ribbonBestRule) {
        this.ribbonBestRule = ribbonBestRule;
        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(3000);
        clientHttpRequestFactory.setReadTimeout(3000);
        restTemplate = new RestTemplate(clientHttpRequestFactory);
    }

    @Override
    public boolean isAlive(Server server) {
        boolean alive = true;
        ServerStats serverStat = ribbonBestRule.getLoadBalancerStats().getSingleServerStat(server);
        if (serverStat.isCircuitBreakerTripped()) {
            alive = checkAlive(server);
        }
        if (!alive) {
            serverStat.incrementSuccessiveConnectionFailureCount();
        }
        return alive;
    }

    private boolean checkAlive(Server server) {
        try {
            String url = "http://" + server.getId() + "/actuator/info";
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            return response.getStatusCodeValue() == HttpStatus.OK.value();
        } catch (Exception e) {
            log.error("serverId={} unavailable", server.getId());
            return false;
        }
    }
}
